window = {};

function fn() {
    console.log("alen");
    var jay = "alex";
}

fn();

// 任何语言在执行的时候，要么是编译，要么是解释，总之要翻译成计算机认识的东西

function fun() {
    // var jar; // 自动的把函数中所有的变量提前声明
    // console.log("你好", jar); // undefined
    // console.log("你好", jar); // undefined
    let jay = "周杰伦";
}

fun();

// 变量的提升，提前把后面需要的变量提前声明
//  但是这不一定是好事
// 为了规范js的语法逻辑，再es6中提出这样一种方式来创建变量
// let ,也是一个声明变量的关键字，但是let没有变量的提升
// const 也可以声明变量， 同样也没有变量的提升，它声明出来的变量不能被重新赋值
(function () {
    const ACE = 15;
    console.log(ACE);
    console.log(ACE + 1);
    // ACE = 2345;    // error
})()


// 重点 在同一个作用域下，let 和 const 声明的变量，是不能重复声明

function func() {
    let name = "alice";
    console.log(name);

    function gn() {
        let firstName = "约翰";
        console.log(firstName);
    }

    gn();
}

func();

// 作用域, 一个变量可以被访问的位置
// 全局作用域
// 在js中window对象就是全局作用域
var callName = "小帅"; //  window.callName = "小帅";
console.log(callName);
//console.log(window.callName);   // nodejs  需要声明window

let Name = "大帅"; // 不会被放到全局
console.log(Name);      // let 声明的东西不会被放入全局

var hello = "hello"; // 往全局放东西

window.alen = "alen";// 也是向全局放东西

// 实际中的 js
(function (a, b) {
    a();
})(function () {
    var gn = function () {
        console.log("逻辑代码...");
    };
    // 我们后期会植入我们的代码, 把gn导出
    // 把gn放出去. 放到全局. 方便我们使用
    window.gn = gn;

}, function () {
});
// 外面随便用
// gn();
window.gn();

// 局部作用域
var a = 88;

function fun() {
    var a = 10; // 局部作用域       只能在函数内部使用的变量
    // 此时， 我们希望外面能访问这个a
    window.a = a;
}

fn();
console.log(a); // 全局？

function fn() {
    var a = 10

    function gn() {
        var a = 33;

        function mn() {
            var a = 100;
        }

        mn();

        console.log(a);
    }

    gn();
}

fn();


// 变量的查找路径
// 注意, 参数是 局部变量
// 使用一个变量的时候. 首先, 先在自己的作用域里找
// 如果找到了就用. 如果找不到....向外找一层.
// 如果找到了. 就用, 如果找不到. 继续向外找
// python也是如此.